<template>
    <div class="lg-dialog__wrapper" v-if="resetDom">
        <div
            :class="['lg-dialog',{[animationDefault]: animationDefault},{'lg-dialog--visible': visible}, {[animationVisible]: visible}, {[customClass]: customClass}]"
            :style="`${width ? 'width:' + width + ';' : ''}${top ? 'top:' + top + ';' : ''}`"
        >
            <i v-if="showClose && destroyDom" class="lg-dialog__close iconfont icon-simplicityClose" @click="onClose"/>
            <slot name="header" v-if="headerSlot && destroyDom">
                <h3 class="lg-dialog__header">{{title}}</h3>
            </slot>
            <div class="lg-dialog__content">
                <slot v-if="destroyDom">
                </slot>
            </div>
            <slot name="footer" v-if="destroyDom"/>
        </div>
        <div :class="['lg-dialog__overlay', {pointer: closeOnClickModal}]" v-if="modal && destroyDom" @click="onClickCloseOverlay"></div>
    </div>
</template>

<script>
export default {
  name: 'lgDialog',
  props: {
    //  组件显示状态
    visible: {
      type: Boolean,
      default: false
    },
    // 标题
    title: {
      type: String,
      default: 'Modal Dialog'
    },
    // dialog宽度
    width: {
      type: String,
      default: '50%'
    },
    // dialog距离顶部的高度
    top: {
      type: String,
      default: '15vh'
    },
    // 是否显示header内容，即标题栏
    headerSlot: {
      type: Boolean,
      default: true
    },
    // 是否需要遮罩层
    modal: {
      type: Boolean,
      default: true
    },
    // 是否可以通过点击 overlay 关闭 Dialog
    closeOnClickModal: {
      type: Boolean,
      default: true
    },
    // 是否可以通过按下 ESC 关闭 Dialog
    closeOnPressEscape: {
      type: Boolean,
      default: true
    },
    // 是否在 Dialog 出现时将 body 滚动锁定
    lockScroll: {
      type: Boolean,
      default: true
    },
    // 自定义类名
    customClass: {
      type: String,
      default: ''
    },
    // 是否显示关闭按钮
    showClose: {
      type: Boolean,
      default: true
    },
    // 关闭后重置 Dialog
    resetDialog: {
      type: Boolean,
      default: false
    },
    // 关闭时销毁 Dialog 中的元素
    destroyOnClose: {
      type: Boolean,
      default: false
    },
    // Dialog 切换效果
    animation: {
      type: String,
      default: 'scale'  // 参数 scale right spaper
    },
    // 参数 before-close 关闭前的回调
    // 事件 open Dialog 打开的回调
    // 事件 close closed Dialog 关闭的回调
  },
  data () {
    return {
      resetDom: true,
      destroyDom: true,
      animationDefault: '',
      animationVisible: ''
    }
  },
  watch: {
    visible: {
      handler (newVal) {
        newVal && this.callbackKey('open', newVal)
        this.hiddenScroll()
        if (newVal) {
          this.onPressEscape()
          if (this.destroyOnClose) {
            this.destroyDom = true
          }
        } else {
          setTimeout(() => {
            if (this.resetDialog) {
              this.resetDom = false
            }
            if (this.destroyOnClose) {
              this.destroyDom = false
            }
            this.$nextTick(() => {
              if (this.resetDialog) {
                this.resetDom = true
              }
              document.removeEventListener('keyup', this.onKeyup, true)
            })
          }, 500)
        }
      },
      immediate: true
    },
    animation: {
        handler(newVal) {
           this.animationDefault = `lg-dialog-${newVal}`
           this.animationVisible = `lg-dialog-${newVal}__visible`
        },
        immediate: true
    }
  },
  methods: {
    hiddenScroll () {
      let body = document.body
      if (this.lockScroll && this.visible) {
        body.style.overflow = 'hidden'
      } else {
        let body = document.body
        body.style.overflow = ''
      }
    },
    onClose () {
      if (this.$attrs['before-close'] && !(this.$attrs['before-close'](this))) return false
      this.callbackKey('close', false)
      this.callbackKey('update:visible', false)
      setTimeout(() => {
        this.callbackKey('closed', false)
      }, 30)
    },
    onClickCloseOverlay () {
      if (!this.closeOnClickModal) return false
      this.onClose()
    },
    onPressEscape () {
      if (!this.closeOnPressEscape) return false
      this.$nextTick(() => {
        document.addEventListener('keyup', this.onKeyup, true)
      })
    },
    onKeyup (e) {
      if (e.keyCode == 27) {
        this.onClose()
      }
    },
    callbackKey (key, data) {
      this.$emit(key, data)
    }
  },
  destroyed() {
      if (!this.closeOnPressEscape) return false
      document.removeEventListener('keyup', this.onKeyup, true)
  }
}
</script>

<style lang="less" scoped>
.lg-dialog__wrapper{
    .lg-dialog {
        position: fixed;
        left: 50%;
        width: 50%;
        z-index: 2001;
        height: auto;
        border-radius: 5px;
        background: #fff;
        visibility: hidden;
        -webkit-backface-visibility: hidden;
        -moz-backface-visibility: hidden;
        backface-visibility: hidden;
        opacity: 0;
        -webkit-transition: all 0.3s;
        -moz-transition: all 0.3s;
        transition: all 0.3s;
        .lg-dialog__content {
            padding: 20px 20px 30px;
            height: auto;
        }
        .lg-dialog__header{
            padding: 0;
            margin: 0;
            padding: 20px 20px 10px;
        }
        .lg-dialog__footer{
            padding: 10px 20px 20px;
            text-align: right;
        }
        .lg-dialog__close{
            position: absolute;
            right: 20px;
            top: 20px;
            cursor: pointer;
            color: #bbb;
            font-size: 22px;
        }
    }
    .lg-dialog__overlay {
        position: fixed;
        width: 100%;
        height: 100%;
        visibility: hidden;
        top: 0;
        left: 0;
        z-index: 2000;
        opacity: 0;
        background: rgba(0,0,0,.5);
        -webkit-transition: all 0.4s;
        -moz-transition: all 0.4s;
        transition: all 0.4s;
    }
    .lg-dialog--visible{
        opacity: 1;
        visibility: visible;
        -webkit-backface-visibility: visible;
        -moz-backface-visibility: visible;
        backface-visibility: visible;
        & ~ .lg-dialog__overlay {
            opacity: 1;
            visibility: visible;
            -webkit-backface-visibility: visible;
            -moz-backface-visibility: visible;
            backface-visibility: visible;
        }
    }
}
// 样式模版专用
.lg-dialog{
  &-scale{
    -webkit-transform: translateX(-50%) scale(.8);
    -moz-transform: translateX(-50%) scale(.8);
    -ms-transform: translateX(-50%) scale(.8);
    transform: translateX(-50%) scale(.8);
  }
  &-scale__visible{
    -webkit-transform: translateX(-50%) scale(1);
    -moz-transform: translateX(-50%) scale(1);
    -ms-transform: translateX(-50%) scale(1);
    transform: translateX(-50%) scale(1);
  }
  &-right{
	-webkit-transform: translateX(-20%);
	-moz-transform: translateX(-20%);
	-ms-transform: translateX(-20%);
	transform: translateX(-20%);
  }
  &-right__visible{
	-webkit-transform: translateX(-50%);
	-moz-transform: translateX(-50%);
	-ms-transform: translateX(-50%);
	transform: translateX(-50%);
  }
  &-spaper{
	-webkit-transition: all 0.5s;
	-moz-transition: all 0.5s;
	transition: all 0.5s;
	-webkit-transform: scale(0) rotate(720deg) translateX(-50%);
	-moz-transform: scale(0) rotate(720deg) translateX(-50%);
	-ms-transform: scale(0) rotate(720deg) translateX(-50%);
	transform: scale(0) rotate(720deg) translateX(-50%);
    transform-origin: left center;
  }
  &-spaper__visible{
	-webkit-transition: all 0.5s;
	-moz-transition: all 0.5s;
	transition: all 0.5s;
	-webkit-transform: scale(1) rotate(0deg) translateX(-50%);
	-moz-transform: scale(1) rotate(0deg) translateX(-50%);
	-ms-transform: scale(1) rotate(0deg) translateX(-50%);
	transform: scale(1) rotate(0deg) translateX(-50%);
  }
}
.pointer{
    cursor: pointer;
}
</style>
